package com.yanyilu.basing.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yanyilu.basing.common.R;
import com.yanyilu.basing.entity.*;
import com.yanyilu.basing.entity.dto.OrderDTO;
import com.yanyilu.basing.mapper.*;
import com.yanyilu.basing.service.IOrderFormService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.yanyilu.basing.util.IpUtil;
import com.yanyilu.basing.util.TimeUtil;
import com.yanyilu.basing.wxpay.MyPayConfig;
import com.yanyilu.basing.wxpay.WXPay;
import com.yanyilu.basing.wxpay.WXPayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Sxx
 * @since 2020-10-27
 */
@Service
public class OrderFormServiceImpl extends ServiceImpl<OrderFormMapper, OrderForm> implements IOrderFormService {
    @Autowired
    OrderFormMapper orderFormMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    ActivityMapper activityMapper;

    @Autowired
    MyPayConfig myPayConfig;

    @Autowired
    OpenidUserMapper openidUserMapper;

    @Autowired
    WxPayMapper wxPayMapper;

    //生成订单返回支付详情结果
    @Override
    @Transactional
    public R getOrder(Integer userId) {
        OrderForm orderForm;
        orderForm = orderFormMapper.selectByUserId(userId);
        //查询用户
        User user = userMapper.selectById(userId);
        //查询活动表
        Activity activity = activityMapper.selectById(1);
        int time = TimeUtil.getTime();
        if(null == orderForm){
            //创建订单
            if(time < activity.getSignUpStartTime()){
                return R.error("活动暂未开始");
            }else if(activity.getSignUpEndTime() < time){
                return R.error("当前活动已结束");
            }
            //System.out.println(user);
            //System.out.println(user.getUserName());
            //设置用户id
            orderForm = new OrderForm();
            orderForm.setUserId(userId);
            //设置用户名
            orderForm.setUserName(user.getUserName());
            //设置时间
            orderForm.setAddTime(time);
            //设置按钮状态
            orderForm.setBtnStatus(0);
            //设置联系方式
            orderForm.setContactDetails(user.getContactDetails());
            //设置运费
            orderForm.setDeposit(new BigDecimal(0));
            //设置鞋码
            orderForm.setShoeSize(user.getShoeSize());
            //生成订单号
            orderForm.setOrderNumber(getOrderIdByUUId());
            //设置商品名称
            orderForm.setGoodsName("贝生领步者");
            //设置收货地址
            orderForm.setShippingAddr(user.getShippingAddr());
            orderForm.setAddr(user.getAddr());
            //设置交易状态
            orderForm.setTradingStatus(0);
            //设置物流状态
            orderForm.setMailStatus(0);
            //设置报名费
            orderForm.setApplyFee(activity.getApplyFee());
            //设置押金
            orderForm.setDeposit(activity.getDeposit());

            orderForm.setShipCost(new BigDecimal(0));
            //设置金额
            orderForm.setAmount(activity.getApplyFee());
            //保存表
            orderFormMapper.insert(orderForm);
        }else{
            orderForm.setUserId(userId);
            //设置用户名
            orderForm.setUserName(user.getUserName());
            //设置时间
            orderForm.setAddTime(time);
            //设置按钮状态
            orderForm.setBtnStatus(0);
            //设置联系方式
            orderForm.setContactDetails(user.getContactDetails());
            //设置运费
            orderForm.setDeposit(new BigDecimal(0));
            //设置鞋码
            orderForm.setShoeSize(user.getShoeSize());
            //生成订单号
            orderForm.setOrderNumber(getOrderIdByUUId());
            //设置商品名称
            orderForm.setGoodsName("贝生领步者");
            //设置收货地址
            orderForm.setShippingAddr(user.getShippingAddr());
            //设置范围地址
            orderForm.setAddr(user.getAddr());
            //设置物流状态
            orderForm.setMailStatus(0);
            //设置交易状态
            orderForm.setTradingStatus(0);
            //设置报名费
            orderForm.setApplyFee(activity.getApplyFee());
            //设置押金
            orderForm.setDeposit(activity.getDeposit());

            orderForm.setShipCost(new BigDecimal(0));
            //设置金额
            orderForm.setAmount(activity.getApplyFee());
            //保存表
            orderFormMapper.updateById(orderForm);
        }

        //获取order
        OrderDTO orderDTO = new OrderDTO();
        orderDTO.setApplyFee(orderForm.getApplyFee());
        orderDTO.setDeposit(orderForm.getDeposit());
        orderDTO.setRealPay(orderForm.getAmount());
        orderDTO.setUserName(orderForm.getUserName());
        orderDTO.setOrderId(orderForm.getOrderFormId());
        orderDTO.setTotalPay(orderForm.getAmount());

        return R.ok().put("order",orderDTO);
    }

    /**
     * 订单详情
     * @param userId
     * @return
     */
    @Override
    public R getOrderInfo(Integer userId) {
        OrderForm orderForm = orderFormMapper.selectByUserId(userId);
        return null != orderForm ? R.ok().put("orderForm",orderForm) : R.error("暂未获取到数据");
    }

    /**
     * 统一下单
     * @param userId
     * @return
     */
    @Override
    public R unifiedorder(Integer userId, HttpServletRequest request) {
        OrderForm orderForm = orderFormMapper.selectByUserId(userId);

        String openid = openidUserMapper.selectOpenidByUserId(userId);
        try {

            //商品名称
            String body = "贝生付款中心-活动报名费";
            //获取本机的ip地址
            String spbill_create_ip = IpUtil.getIpAddr(request);
            //System.out.println(spbill_create_ip);
            //商户订单号
            String outTradeNo = orderForm.getOrderNumber();
            String money = String.valueOf(orderForm.getApplyFee().intValue()*100);//支付金额，单位：分，这边需要转成字符串类型，否则后面的签名会失败

            Map<String, String> packageParams = new HashMap<>();

            packageParams.put("body", body);
            packageParams.put("product_id", "1");//商品id
            packageParams.put("out_trade_no", outTradeNo);//商户订单号
//            packageParams.put("total_fee","1");//支付金额，这边需要转成字符串类型，否则后面的签名会失败
            packageParams.put("total_fee",money);//支付金额，这边需要转成字符串类型，否则后面的签名会失败
            packageParams.put("spbill_create_ip", spbill_create_ip);
            packageParams.put("openid",openid);
            //packageParams.put("attach", "PC");//自定义参数
            //System.out.println("key==="+myPayConfig.getKey());

            //创建微信pay对象
            WXPay wxPay = new WXPay(myPayConfig,myPayConfig.getNotify_url());

            //调用统一下单支付
            Map<String, String> resMap = wxPay.unifiedOrder(packageParams);
            Set<Map.Entry<String, String>> entries = resMap.entrySet();
//            for (Map.Entry<String, String> entry : entries) {
//                System.out.println(entry);
//            }
            //返回字段很多，这里只取我们所需的字段
//            String return_msg = resMap.get("return_msg");//返回信息
            //System.out.println(return_msg);
            String return_code = resMap.get("return_code");//状态码
            String result_code = resMap.get("result_code");//业务结果
            //根据微信文档return_code 和result_code都为SUCCESS的时候才会返回code_url
            if ("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code)) {
                String prepay_id = resMap.get("prepay_id");
                HashMap<String, String> resData = new HashMap<>();
                resData.put("appId",myPayConfig.getAppID());
                resData.put("timeStamp",TimeUtil.getTimeStr10());
                resData.put("nonceStr",WXPayUtil.generateNonceStr());
                resData.put("package","prepay_id="+prepay_id);
                resData.put("signType","MD5");
                String paySign = WXPayUtil.generateSignature(resData, myPayConfig.getKey());
                resData.put("paySign",paySign);
                return R.ok().put("resData",resData);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.error("请求支付失败，请稍后重试！");
    }

    /**
     * 回调处理
     * @param request
     * @return
     */
    @Override
    @Transactional
    public boolean callBack(HttpServletRequest request){
        System.out.println("微信支付回调");
        Map<String, String> respMap;
        try{
            InputStream inStream = request.getInputStream();
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            String resultxml = new String(outSteam.toByteArray(), "utf-8");
            respMap = WXPayUtil.xmlToMap(resultxml);
            //System.out.println(respMap);
            outSteam.close();
            inStream.close();
            String return_code = respMap.get("return_code");
            if("SUCCESS".equals(return_code)){
                String openid = respMap.get("openid");
                String out_trade_no	 = respMap.get("out_trade_no");
                String transaction_id	 = respMap.get("transaction_id");
                String time_end	 = respMap.get("time_end");
                String total_fee = respMap.get("total_fee");
                //获取用户
                //TODO
                User user = userMapper.selectByOpenid(openid);
                user.setIsPay(1);
                //获取订单
                OrderForm orderForm = orderFormMapper.selectByUserId(user.getUserId());
                orderForm.setBtnStatus(1);
                orderForm.setTradingStatus(1);

                WxPay wxPay = new WxPay();
                wxPay.setPayNumber(out_trade_no);
                wxPay.setWxPayNo(transaction_id);
                wxPay.setPayTime(time_end);
                wxPay.setUserId(user.getUserId());
                wxPay.setAmount(new BigDecimal(Integer.valueOf(total_fee)/100));
                userMapper.updateById(user);
                orderFormMapper.updateById(orderForm);
                wxPayMapper.insert(wxPay);
                return true;
            }
        }catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 修改订单
     * @param orderForm
     * @return
     */
    @Override
    public R updateOrder(OrderForm orderForm,Integer userId) {
        OrderForm orderForm1 = orderFormMapper.selectByUserId(userId);
        if(null == orderForm1){
            return R.error();
        }
        if(null != orderForm1.getMailStatus() && 0 != orderForm1.getMailStatus()){
            return R.error("已发货，暂不可修改");
        }
        orderForm.setOrderFormId(orderForm1.getOrderFormId());
        orderFormMapper.updateById(orderForm);
        return R.ok().put("orderForm",orderFormMapper.selectById(orderForm.getOrderFormId()));
    }

    /**
     * 确认收货
     * @param orderFormId
     * @return
     */
    @Transactional
    @Override
    public R checkOrder(Integer orderFormId) {
        OrderForm orderForm = orderFormMapper.selectById(orderFormId);
        //验证收货时间
        Activity activity = activityMapper.selectById(1);
        int time = TimeUtil.getTime();
        if(time < activity.getReceiveStartTime()){
            return R.error("暂未到收货时间!");
        }
        User user = new User();
        user.setUserId(orderForm.getUserId());
        user.setIsReceive(1);
        orderForm.setBtnStatus(3);
        orderForm.setMailStatus(2);
        //更新订单表
        orderFormMapper.updateById(orderForm);
        //更新用户表
        userMapper.updateById(user);
        return R.ok().put("orderForm",orderForm);
    }
    /**
     * 订单列表
     * @param page
     * @param limit
     * @param orderNumber
     * @return
     */
    @Override
    public R adminOrderFormList(Integer page, Integer limit, String orderNumber) {
        PageHelper.startPage(page,limit);
        List<OrderForm> list = orderFormMapper.selectAll(orderNumber);
        PageInfo<OrderForm> pageInfo = new PageInfo<>(list);
        return R.ok().put("list",pageInfo.getList()).put("count",pageInfo.getTotal()).put("pages",pageInfo.getPages());
    }


    public R adminDelete(Integer orderFormId){
        orderFormMapper.deleteById(orderFormId);
        return R.ok();
    }

    @Override
    public R adminUpdate(OrderForm orderForm) {
        orderFormMapper.updateById(orderForm);
        return R.ok();
    }

    @Override
    public OrderForm orderByCon(String contactDetails) {
        return orderFormMapper.selectByContactDetails(contactDetails);
    }


    //生成订单号
    public  String getOrderIdByUUId() {
        int first = new Random(10).nextInt(8) + 1;
        //System.out.println(first);
        int hashCodeV = UUID.randomUUID().toString().hashCode();
        if (hashCodeV < 0) {//有可能是负数
            hashCodeV = -hashCodeV;
        }
        // 0 代表前面补充0
        // 4 代表长度为4
        // d 代表参数为正数型
        return first + String.format("%015d", hashCodeV);
    }


}
